
/*********************************  COPYRIGHT 2020 --------  *********  BEGIN OF FILE  ********************************/

/**********************************************************************
* @file           : pwm.c
* @author         : --
* @version        : --
* @date           : 2020-09-09
* @brief          : pwm program body
* @Description    : --
**********************************************************************/

/*-- Includes -------------------------------------------------------*/
#include "pwm.h"



/*-- Private typedef ------------------------------------------------*/
/*-- Private define -------------------------------------------------*/

//-----------------------------------------//
#define BLDC_TIM   TIM1   //TIM1_CH3N

#define BLDC_HIN1_GPIO   GPIOB
#define BLDC_HIN1_PIN   GPIO_Pin_15
#define	BLDC_HIN1_CLK   RCC_APB2Periph_GPIOB

#define BLDC_HIN2_GPIO   GPIOB
#define BLDC_HIN2_PIN   GPIO_Pin_14
#define	BLDC_HIN2_CLK   RCC_APB2Periph_GPIOB

#define BLDC_HIN3_GPIO   GPIOB
#define BLDC_HIN3_PIN   GPIO_Pin_13
#define	BLDC_HIN3_CLK   RCC_APB2Periph_GPIOB

#define HEAT_CTRL_GPIO   GPIOA
#define HEAT_CTRL_PIN   GPIO_Pin_1
#define	HEAT_CTRL_CLK   RCC_APB2Periph_GPIOA
#define HEAT_CTRL_TIM   TIM2   //TIM2_CH2



/*-- Private macro --------------------------------------------------*/
/*-- Private variables ----------------------------------------------*/

//-----------------------------------------//
u16 PWM_BLDC_Period;
u16 PWM_HEAT_Period;			//加热的总周期



/*-- Private functions ----------------------------------------------*/

/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
static void PWM_GPIO_Config(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure; 

	// TIM clock enable
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
	
	// GPIO clock enable
	RCC_APB2PeriphClockCmd(BLDC_HIN1_CLK | BLDC_HIN2_CLK | BLDC_HIN3_CLK | RCC_APB2Periph_AFIO, ENABLE);//HEAT_CTRL_CLK | 

	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
	
	GPIO_InitStructure.GPIO_Pin = BLDC_HIN1_PIN;
	GPIO_Init(BLDC_HIN1_GPIO, &GPIO_InitStructure); 

	GPIO_InitStructure.GPIO_Pin = BLDC_HIN2_PIN;
	GPIO_Init(BLDC_HIN2_GPIO, &GPIO_InitStructure); 

	GPIO_InitStructure.GPIO_Pin = BLDC_HIN3_PIN;
	GPIO_Init(BLDC_HIN3_GPIO, &GPIO_InitStructure); 

//	GPIO_InitStructure.GPIO_Pin = HEAT_CTRL_PIN;
//	GPIO_Init(HEAT_CTRL_GPIO, &GPIO_InitStructure); 
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
static void PWM_BLDC_Config(u16 period)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;	
	uint16_t PrescalerValue = 0;
	
	PrescalerValue = (uint16_t) (SystemCoreClock / 10000) - 1;
	if (period == 0)
	{
		PWM_BLDC_Period = 0;
	}
	else
	{
		PWM_BLDC_Period = period - 1;
	}
	
	// Time Base configuration
	TIM_TimeBaseStructure.TIM_Prescaler = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_Period = PWM_BLDC_Period;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

	// Channel Configuration in PWM mode
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
	TIM_TimeBaseInit(BLDC_TIM, &TIM_TimeBaseStructure);

	// BLDC_CTRL	
	TIM_OC1Init(BLDC_TIM, &TIM_OCInitStructure);
	TIM_OC1PreloadConfig(BLDC_TIM, TIM_OCPreload_Enable);
	TIM_SetCompare3(BLDC_TIM, 0);

	TIM_OC2Init(BLDC_TIM, &TIM_OCInitStructure);
	TIM_OC2PreloadConfig(BLDC_TIM, TIM_OCPreload_Enable);
	TIM_SetCompare3(BLDC_TIM, 0);

	TIM_OC3Init(BLDC_TIM, &TIM_OCInitStructure);
	TIM_OC3PreloadConfig(BLDC_TIM, TIM_OCPreload_Enable);
	TIM_SetCompare3(BLDC_TIM, 0);

	// TIM1 enable counter
	TIM_Cmd(BLDC_TIM, ENABLE);
	// TIM1 Main Output Enable
	TIM_CtrlPWMOutputs(BLDC_TIM, ENABLE);
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
static void PWM_HEAT_Config(u16 period)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;	
	uint16_t PrescalerValue = 0;
	
	PrescalerValue = (uint16_t) (SystemCoreClock / 10000) - 1;
	if (period == 0)
	{
		PWM_HEAT_Period = 0;
	}
	else
	{
		PWM_HEAT_Period = period - 1;
	}
	
	// Time Base configuration
	TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;				//7200
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;			//10k
	TIM_TimeBaseStructure.TIM_Period = PWM_HEAT_Period;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

	// Channel Configuration in PWM mode
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
	TIM_TimeBaseInit(HEAT_CTRL_TIM, &TIM_TimeBaseStructure);

	// HEAT_CTRL	
	TIM_OC2Init(HEAT_CTRL_TIM, &TIM_OCInitStructure);
	TIM_OC2PreloadConfig(HEAT_CTRL_TIM, TIM_OCPreload_Enable);
	TIM_SetCompare2(HEAT_CTRL_TIM, PWM_HEAT_Period);
	
	// TIM1 enable counter
	TIM_Cmd(HEAT_CTRL_TIM, ENABLE);
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : bldc_period: bldc control pwm period, unit in us
*                  heat_period: heat control pwm period, unit in us
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void PWM_Config(void)
{
	PWM_GPIO_Config();
	PWM_BLDC_Config(PWM_BLDC_PERIOD);
//	PWM_HEAT_Config(PWM_HEAT_PERIOD);			//1hz
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void PWM_BLDC_Stop(u8 ch)
{
	switch(ch)
	{
		case 1:
			TIM_SetCompare3(BLDC_TIM, PWM_BLDC_PERIOD);
			TIM_CCxNCmd(BLDC_TIM, TIM_Channel_3, TIM_CCxN_Disable);
			break;

		case 2:
			TIM_SetCompare2(BLDC_TIM, PWM_BLDC_PERIOD);
			TIM_CCxNCmd(BLDC_TIM, TIM_Channel_2, TIM_CCxN_Disable);
			break;

		case 3:
			TIM_SetCompare1(BLDC_TIM, PWM_BLDC_PERIOD);
			TIM_CCxNCmd(BLDC_TIM, TIM_Channel_1, TIM_CCxN_Disable);
			break;
		
		default:			
			break;	
	}	
}


/**********************************************************************
* @Fuctionname   : None
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void PWM_BLDC_SetWidth(u8 ch, u16 width)
{	
	switch(ch)
	{
		case 1:
			TIM_CCxNCmd(BLDC_TIM, TIM_Channel_3, TIM_CCxN_Enable);
			if (width > PWM_BLDC_Period)
			{
				TIM_SetCompare3(BLDC_TIM, 0);
			}
			else
			{
				TIM_SetCompare3(BLDC_TIM, PWM_BLDC_PERIOD - width);
			}
			break;

		case 2:
			TIM_CCxNCmd(BLDC_TIM, TIM_Channel_2, TIM_CCxN_Enable);
			if (width > PWM_BLDC_Period)
			{
				TIM_SetCompare2(BLDC_TIM, 0);
			}
			else
			{
				TIM_SetCompare2(BLDC_TIM, PWM_BLDC_PERIOD - width);
			}
			break;

		case 3:
			TIM_CCxNCmd(BLDC_TIM, TIM_Channel_1, TIM_CCxN_Enable);
			if (width > PWM_BLDC_Period)
			{
				TIM_SetCompare1(BLDC_TIM, 0);
			}
			else
			{
				TIM_SetCompare1(BLDC_TIM, PWM_BLDC_PERIOD - width);
			}
			break;
		
		default:			
			break;	
	}		
}


/**********************************************************************
* @Fuctionname   : 加热PWM输出（可控硅）
* @Brief         : None
* @Input         : None
* @Output        : None
* @Return        : None
* @Remark        : None
**********************************************************************/
void PWM_HEAT_SetWidth(u16 width)
{
	if (width > PWM_HEAT_PERIOD)
	{
		TIM_SetCompare2(HEAT_CTRL_TIM, 0);
	}
	else
	{
		TIM_SetCompare2(HEAT_CTRL_TIM, PWM_HEAT_PERIOD - width);
	}
}

/*********************************  COPYRIGHT 2020 --------  *********  END OF FILE  **********************************/
